package com.cskaoyan.javase.oop1._5this;

/**
 * this关键字
 * 学习完对象与类后，做以下练习：
 * 创建一个汽车类，有颜色（color）和速度（speed）两个属性，行为是可以跑（run）。
 *
 * 需求:
 *      1.要求在run方法中加上自身对象的属性,然后输出
 *      2.现在要求给run方法增加一个参数,传入一个speed速度,然后调用该方法
 *          我们发现在方法体中直接输出同名speed,输出的是方法的实参speed
 *          这是一种就近原则的体现
 *
 * 思考:
 *      在以上需求中,访问speed会变成方法的形参,那么如何修改代码,去访问同名的成员变量speed呢?
 *      这里就需要使用this关键字
 *
 * 何为this关键字?
 * 在Java的一个类中,任意的一个成员方法中
 * 它的形参列表中,都会隐含一个传参
 * 传入的是当前对象,这个当前对象用this关键字指向
 * this指向当前对象,this是一个引用
 *
 * 什么是当前对象?
 * 对于成员方法而言,它的调用必然需要一个对象来调用它
 * 这时,谁来调用该成员方法,对于该成员方法而言,它就是当前对象.
 *
 * 以上,要想在成员方法中访问同名的成员变量,应该使用this关键字做区分,因为它指向当前对象,是一个引用
 * 具体来说,就是:
 *      this.成员变量名访问
 *
 * 总结this关键字:
 *      1.this关键字指向当前对象,是类中成员方法的一个隐式传参
 *          这实际上,也是为什么成员方法可以直接访问类中成员变量的原因
 *          与之相对应的,static修饰的方法,这种方法中是没有this传参的,所以它是不能直接访问类中成员变量和方法的.
 *
 *      2.特殊情况下，当成员方法中的局部变量和成员变量同名时，可以用 "this."访问 来表示访问同名成员变量，来和同名局部变量做区分。这种情况，this是不能省略的。
 *      但是如果仅在成员方法中访问不同名的成员变量,或者访问方法
 *      是没有必要加上this的,加了反而画蛇添足.
 *
 *      3.当然this关键字的作用远不止此，我们在后面还会学习.
 *
 * @since 17:23
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Car c = new Car();
        c.color = "红色";
        // 对象名点赋值,是创建对象以后的赋值手段
        c.speed = 80;
        System.out.println(c.color);
        System.out.println(c.speed);
        // c.run();
        /*
            c引用指向的对象来调用run方法
            这时c对象就是当前对象
         */
        c.run(120);
        System.out.println(c);

        System.out.println("-----------------");
        Car c2 = new Car();
        c2.run(200);
        System.out.println(c2);
    }
}

// 汽车类
class Car {
    String color;
    /*
        显式赋值是创建对象过程中赋值手段
     */
    int speed = 100;

    public void run(int speed) {
        // this指向当前对象,就是一个引用,可以直接打印
        System.out.println(this);
        gasUp();
        gasUp(100);
        System.out.println(color + "小汽车以每小时" + this.speed + "公里的速度,奔驰在宽敞的大马路上!");
    }
    public void gasUp(){

    }
    public void gasUp(int a){

    }

    public static void test(){
        // System.out.println(speed);
    }
}